Added _gtk_size_group_bump_requisition()
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Wed, 14 Apr 2010 22:07:27 +0000 (18:07 -0400)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Wed, 14 Apr 2010 22:07:27 +0000 (18:07 -0400)
Added a function to update sizegroups in multiple passes, this
way the width and height can be updated in the sizegroups after
querying the extended layout implementor for these.

Implemented this in GtkExtendedLayout, sizegroups should be working reasonably now.

gtk/gtkextendedlayout.c
gtk/gtklabel.c
gtk/gtksizegroup.c
gtk/gtksizegroup.h

index 0da095342b280387da1058dfb600ccd6d2b75a2e..dcc3e6ca4edf2c7fe1d1b6a61bae68522c866d4f 100644 (file)
@@ -157,9 +157,14 @@ gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout,
                                                                 &minimum_width, 
                                                                 &natural_width);
 
+      minimum_width = MAX (minimum_width, requisition.width);
+      natural_width = MAX (natural_width, requisition.width);
 
-      cached_size->minimum_size = MAX (minimum_width, requisition.width);
-      cached_size->natural_size = MAX (natural_width, requisition.width);
+      /* XXX Possibly we should update this with minimum values instead */
+      _gtk_size_group_bump_requisition (GTK_WIDGET (layout), GTK_SIZE_GROUP_HORIZONTAL, natural_width);
+
+      cached_size->minimum_size = minimum_width;
+      cached_size->natural_size = natural_width;
       cached_size->for_size     = -1;
       cached_size->age          = aux_info->cached_width_age;
 
@@ -174,6 +179,8 @@ gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout,
   if (natural_width)
     *natural_width = cached_size->natural_size;
 
+  g_assert (!minimum_width || !natural_width || *minimum_width <= *natural_width);
+
 #if DEBUG_EXTENDED_LAYOUT
   g_message ("%s returning minimum width: %d and natural width: %d",
             G_OBJECT_TYPE_NAME (layout), 
@@ -228,8 +235,14 @@ gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout,
                                                                  &minimum_height, 
                                                                  &natural_height);
 
-      cached_size->minimum_size = MAX (minimum_height, requisition.height);
-      cached_size->natural_size = MAX (natural_height, requisition.height);
+      minimum_height = MAX (minimum_height, requisition.height);
+      natural_height = MAX (natural_height, requisition.height);
+
+      /* XXX Possibly we should update this with minimum values instead */
+      _gtk_size_group_bump_requisition (GTK_WIDGET (layout), GTK_SIZE_GROUP_VERTICAL, natural_height);
+
+      cached_size->minimum_size = minimum_height;
+      cached_size->natural_size = natural_height;
       cached_size->for_size     = -1;
       cached_size->age          = aux_info->cached_height_age;
 
@@ -244,6 +257,7 @@ gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout,
   if (natural_height)
     *natural_height = cached_size->natural_size;
 
+  g_assert (!minimum_height || !natural_height || *minimum_height <= *natural_height);
 
 #if DEBUG_EXTENDED_LAYOUT
   g_message ("%s returning minimum height: %d and natural height: %d",
@@ -301,9 +315,15 @@ gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
                                                                    height,
                                                                    &minimum_width, 
                                                                    &natural_width);
+
+      minimum_width = MAX (minimum_width, requisition.width);
+      natural_width = MAX (natural_width, requisition.width);
+
+      /* XXX Possibly we should update this with minimum values instead */
+      _gtk_size_group_bump_requisition (GTK_WIDGET (layout), GTK_SIZE_GROUP_HORIZONTAL, natural_width);
       
-      cached_size->minimum_size = MAX (minimum_width, requisition.width);
-      cached_size->natural_size = MAX (natural_width, requisition.width);
+      cached_size->minimum_size = minimum_width;
+      cached_size->natural_size = natural_width;
       cached_size->for_size     = height;
       cached_size->age          = aux_info->cached_width_age;
 
@@ -376,9 +396,15 @@ gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
                                                                    width,
                                                                    &minimum_height, 
                                                                    &natural_height);
-      
-      cached_size->minimum_size = MAX (minimum_height, requisition.height);
-      cached_size->natural_size = MAX (natural_height, requisition.height);
+
+      minimum_height = MAX (minimum_height, requisition.height);
+      natural_height = MAX (natural_height, requisition.height);
+
+      /* XXX Possibly we should update this with minimum values instead */
+      _gtk_size_group_bump_requisition (GTK_WIDGET (layout), GTK_SIZE_GROUP_VERTICAL, natural_height);
+
+      cached_size->minimum_size = minimum_height;
+      cached_size->natural_size = natural_height;
       cached_size->for_size     = width;
       cached_size->age          = aux_info->cached_height_age;
 
index f8294f21d5e49d078dff922a3998998efc98fd60..c730e311dc238d4f69521a070a8dee69e755a6f8 100644 (file)
@@ -3253,7 +3253,7 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
       label->layout = backup;
     }
   
-  if (label->single_line_mode)
+  if (label->single_line_mode || label->wrap)
     required_rect.height = get_single_line_height (GTK_WIDGET (label), label->layout);
   
   if (label->have_transform)
@@ -3279,7 +3279,9 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     minimum = required_rect.width + label->misc.xpad * 2;
   else
-    minimum = required_rect.height + label->misc.ypad * 2;
+    {
+      minimum = required_rect.height + label->misc.ypad * 2;
+    }
 
   /* Natural size */
   natural_layout = pango_layout_copy (label->layout);
index b1abfbe6cae28915fc1f6212efa7a8189cc8a51b..43ae77ea5ddd23041c1cbd57c72fda0cd3337671 100644 (file)
@@ -621,7 +621,7 @@ get_base_dimension (GtkWidget        *widget,
 }
 
 static void
-do_size_request (GtkWidget *widget)
+do_size_request (GtkWidget *widget, gint width, gint height)
 {
   if (GTK_WIDGET_REQUEST_NEEDED (widget))
     {
@@ -631,20 +631,35 @@ do_size_request (GtkWidget *widget)
                             "size-request",
                             &widget->requisition);
     }
+  
+  /* Also update size groups from _gtk_size_group_bump_requisition() */
+  widget->requisition.width  = MAX (widget->requisition.width, width);
+  widget->requisition.height = MAX (widget->requisition.height, height);
 }
 
+/* NOTE: This is only ever called for either mode horizontal or mode vertical
+ * but never as both.
+ */
 static gint
 compute_base_dimension (GtkWidget        *widget,
-                       GtkSizeGroupMode  mode)
+                       GtkSizeGroupMode  mode,
+                       gint              minimum)
 {
-  do_size_request (widget);
+  if (mode == GTK_SIZE_GROUP_HORIZONTAL)
+    do_size_request (widget, minimum, -1);
+  else /*  (mode == GTK_SIZE_GROUP_VERTICAL) */
+    do_size_request (widget, -1, minimum);
 
   return get_base_dimension (widget, mode);
 }
 
+/* NOTE: This is only ever called for either mode horizontal or mode vertical
+ * but never as both.
+ */
 static gint
 compute_dimension (GtkWidget        *widget,
-                  GtkSizeGroupMode  mode)
+                  GtkSizeGroupMode  mode,
+                  gint              minimum)
 {
   GSList *widgets = NULL;
   GSList *groups = NULL;
@@ -660,7 +675,7 @@ compute_dimension (GtkWidget        *widget,
   
   if (!groups)
     {
-      result = compute_base_dimension (widget, mode);
+      result = compute_base_dimension (widget, mode, minimum);
     }
   else
     {
@@ -677,7 +692,7 @@ compute_dimension (GtkWidget        *widget,
            {
              GtkWidget *tmp_widget = tmp_list->data;
 
-             gint dimension = compute_base_dimension (tmp_widget, mode);
+             gint dimension = compute_base_dimension (tmp_widget, mode, minimum);
 
              if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden)
                {
@@ -696,12 +711,12 @@ compute_dimension (GtkWidget        *widget,
              if (mode == GTK_SIZE_GROUP_HORIZONTAL)
                {
                  tmp_group->have_width = TRUE;
-                 tmp_group->requisition.width = result;
+                 tmp_group->requisition.width = MAX (result, minimum);
                }
              else
                {
                  tmp_group->have_height = TRUE;
-                 tmp_group->requisition.height = result;
+                 tmp_group->requisition.height = MAX (result, minimum);
                }
              
              tmp_list = tmp_list->next;
@@ -802,7 +817,12 @@ _gtk_size_group_get_child_requisition (GtkWidget      *widget,
  * 
  * Compute the requisition of a widget taking into account grouping of
  * the widget's requisition with other widgets.
- **/
+ *
+ * This is used by #GtkExtendedLayout to obtain minimum value
+ * caps for all values cached and returned to parent containers,
+ * then the extended layout while making its own sizes in multiple
+ * passes updates sizegroups with _gtk_size_group_bump_requisition().
+ */
 void
 _gtk_size_group_compute_requisition (GtkWidget      *widget,
                                     GtkRequisition *requisition)
@@ -815,9 +835,8 @@ _gtk_size_group_compute_requisition (GtkWidget      *widget,
   if (get_size_groups (widget))
     {
       /* Only do the full computation if we actually have size groups */
-      
-      width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL);
-      height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL);
+      width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL, -1);
+      height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL, -1);
 
       if (requisition)
        {
@@ -827,13 +846,48 @@ _gtk_size_group_compute_requisition (GtkWidget      *widget,
     }
   else
     {
-      do_size_request (widget);
+      do_size_request (widget, -1, -1);
       
       if (requisition)
        get_fast_child_requisition (widget, requisition);
     }
 }
 
+
+/**
+ * _gtk_size_group_bump_requisition:
+ * @widget: a #GtkWidget
+ * @mode: either %GTK_SIZE_GROUP_HORIZONTAL or %GTK_SIZE_GROUP_VERTICAL, depending
+ *        on the dimension in which to bump the size.
+ * @size: The new base size in @mode's dimension for the group.
+ *
+ * This function is used to update sizegroup minimum size information
+ * in multiple passes from the new #GtkExtendedLayout manager.
+ */
+void
+_gtk_size_group_bump_requisition (GtkWidget        *widget,
+                                 GtkSizeGroupMode  mode,
+                                 gint              size)
+{
+  initialize_size_group_quarks ();
+
+  if (get_size_groups (widget))
+    {
+      if (mode == GTK_SIZE_GROUP_HORIZONTAL)
+       compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL, size);
+      else
+       compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL, size);
+    }
+  else
+    {
+      if (mode == GTK_SIZE_GROUP_HORIZONTAL)
+       do_size_request (widget, size, -1);
+      else
+       do_size_request (widget, -1, size);
+    }
+}
+
+
 /**
  * _gtk_size_group_queue_resize:
  * @widget: a #GtkWidget
index ecd2ceacf6d60318abe70e68cc6e319a54e4dced..8addb5cd7a1d55736296a42497e9601b6a86527d 100644 (file)
@@ -100,11 +100,15 @@ void             gtk_size_group_remove_widget (GtkSizeGroup     *size_group,
 GSList *         gtk_size_group_get_widgets   (GtkSizeGroup     *size_group);
 
 
-void _gtk_size_group_get_child_requisition (GtkWidget      *widget,
-                                           GtkRequisition *requisition);
-void _gtk_size_group_compute_requisition   (GtkWidget      *widget,
-                                           GtkRequisition *requisition);
-void _gtk_size_group_queue_resize          (GtkWidget      *widget);
+void _gtk_size_group_get_child_requisition (GtkWidget        *widget,
+                                           GtkRequisition   *requisition);
+void _gtk_size_group_compute_requisition   (GtkWidget        *widget,
+                                           GtkRequisition   *requisition);
+void _gtk_size_group_bump_requisition      (GtkWidget        *widget,
+                                           GtkSizeGroupMode  mode,
+                                           gint              size);
+void _gtk_size_group_queue_resize          (GtkWidget        *widget);
+
 
 G_END_DECLS